package com.ruoyi.basebill.task;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qimencloud.api.DefaultQimenCloudClient;
import com.qimencloud.api.scene5uc0mzv618.request.WdtReturnCollectQueryRequest;
import com.qimencloud.api.scene5uc0mzv618.response.WdtReturnCollectQueryResponse;
import com.qimencloud.api.scene5uc0mzv618.response.WdtStockoutCollectQueryResponse;
import com.ruoyi.basebill.domain.OmsSalereturnbill;
import com.ruoyi.basebill.domain.OmsSalereturnbillentry;
import com.ruoyi.basebill.domain.QMBillConfig;
import com.ruoyi.basebill.service.impl.OmsSalereturnbillServiceImpl;
import com.ruoyi.basebill.task.util.OmsTaskUtil;
import com.ruoyi.basedata.domain.BdCustomer;
import com.ruoyi.basedata.domain.BdMaterial;
import com.ruoyi.basedata.domain.BdShop;
import com.ruoyi.basedata.domain.OmsOrgunit;
import com.ruoyi.basedata.service.impl.BdCustomerServiceImpl;
import com.ruoyi.basedata.service.impl.BdMaterialServiceImpl;
import com.ruoyi.basedata.service.impl.BdShopServiceImpl;
import com.ruoyi.basedata.service.impl.OmsOrgunitServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Component("OmsGetWdtSaleIssueReturnBillTask")
public class OmsGetWdtSaleIssueReturnBillTask {

    //注入自己
    @Autowired
    private OmsGetWdtSaleIssueReturnBillTask getWdtSaleIssueReturnBillTask;

    @Autowired
    private ObjectMapper objectMapper;
    //系统参数服务层接口
    @Autowired
    private ISysConfigService sysConfigService;

    //店铺服务层接口
    @Autowired
    private BdShopServiceImpl shopService;

    //客户服务层接口
    @Autowired
    private BdCustomerServiceImpl customerService;

    //物料服务层接口
    @Autowired
    private BdMaterialServiceImpl materialService;

    //销售退货单服务层接口
    @Autowired
    private OmsSalereturnbillServiceImpl salereturnbillService;

    @Autowired
    private OmsOrgunitServiceImpl orgunitService;

    @Transactional(rollbackFor = Exception.class)
    public void getBillData() throws JsonProcessingException, ApiException, ParseException {
        SysConfig qmSaleConfig = sysConfigService.selectConfigByConfigKey("QM_saleRefund_config");
        QMBillConfig qmBillConfig = new QMBillConfig();
        qmBillConfig.setStartTime(LocalDate.now().minusDays(1));
        qmBillConfig.setEndTime(LocalDate.now().minusDays(1));
        qmBillConfig.setShopNo("");
        qmBillConfig.setPageNo(1);
        qmBillConfig.setPageSize(100);
        String s = objectMapper.writeValueAsString(qmBillConfig);
        qmSaleConfig.setConfigValue(s);
        sysConfigService.updateConfig(qmSaleConfig);
        getWdtSaleIssueReturnBillTask.getWdtSaleReturnBill(qmBillConfig);
    }

    @Transactional(rollbackFor = Exception.class)
    public void getBillData(String pageNo,String pageSize,String startDate,String endDate,String shopNo) throws JsonProcessingException, ApiException, ParseException {
        SysConfig qmSaleConfig = sysConfigService.selectConfigByConfigKey("QM_sale_config");
        QMBillConfig qmBillConfig = new QMBillConfig();
        OmsTaskUtil.formatWdtData(pageNo, pageSize, startDate, endDate, shopNo,qmBillConfig);
        String s = objectMapper.writeValueAsString(qmBillConfig);
        qmSaleConfig.setConfigValue(s);
        sysConfigService.updateConfig(qmSaleConfig);
        getWdtSaleIssueReturnBillTask.getWdtSaleReturnBillAllNumber(qmBillConfig);

    }

    public void getWdtSaleReturnBillAllNumber(QMBillConfig qmBillConfig) throws ApiException, JsonProcessingException, ParseException {
        StringBuffer errorMessage =new StringBuffer();
        String qmConfig = sysConfigService.selectConfigByKey("QM_config");
        JSONObject qmConfigJson = JSON.parseObject(qmConfig);
        String qmServerUrl = (String) qmConfigJson.get("QM_serverUrl");
        String qmAppKey = (String) qmConfigJson.get("QM_appKey");
        String qmAppSecret = (String) qmConfigJson.get("QM_appSecret");
        String qmTargetAppKey = (String) qmConfigJson.get("QM_targetAppKey");
        String qmSId = (String) qmConfigJson.get("QM_sId");
        DefaultQimenCloudClient client = new DefaultQimenCloudClient(qmServerUrl, qmAppKey, qmAppSecret);
        WdtReturnCollectQueryRequest req = new WdtReturnCollectQueryRequest();
        req.setTargetAppKey(qmTargetAppKey);
        req.setSid(qmSId);
        if (StringUtils.isNotBlank(qmBillConfig.getShopNo())) {
            req.setShopNo(qmBillConfig.getShopNo());
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        req.setStartTime(qmBillConfig.getStartTime().format(dateTimeFormatter));
        req.setEndTime(qmBillConfig.getEndTime().format(dateTimeFormatter));
        req.setPageNo(String.valueOf(qmBillConfig.getPageNo()));
        req.setPageSize(String.valueOf(qmBillConfig.getPageSize()));
        WdtReturnCollectQueryResponse response = client.execute(req);
        if ("".equals(response.getErrorCode())){
            int totalCount = Integer.parseInt(response.getTotalCount());
            //100是一页的最大数量
            int b = 100;
            int i = totalCount / b + (totalCount % b == 0 ? 0 : 1);
            for (int j = 0; j < i; j++) {
                qmBillConfig.setPageNo(j+1);
                getWdtSaleIssueReturnBillTask.getWdtSaleReturnBill(qmBillConfig);
            }
        } else {
            throw new RuntimeException(response.getMessage());
        }
    }

        @Transactional(rollbackFor = Exception.class)
    void getWdtSaleReturnBill(QMBillConfig qmBillConfig) throws ApiException, JsonProcessingException, ParseException {
        StringBuffer errorMessage =new StringBuffer();
        String qmConfig = sysConfigService.selectConfigByKey("QM_config");
        JSONObject qmConfigJson = JSON.parseObject(qmConfig);
        String qmServerUrl = (String) qmConfigJson.get("QM_serverUrl");
        String qmAppKey = (String) qmConfigJson.get("QM_appKey");
        String qmAppSecret = (String) qmConfigJson.get("QM_appSecret");
        String qmTargetAppKey = (String) qmConfigJson.get("QM_targetAppKey");
        String qmSId = (String) qmConfigJson.get("QM_sId");
        DefaultQimenCloudClient client = new DefaultQimenCloudClient(qmServerUrl, qmAppKey, qmAppSecret);
        WdtReturnCollectQueryRequest req = new WdtReturnCollectQueryRequest();
        req.setTargetAppKey(qmTargetAppKey);
        req.setSid(qmSId);
        if (StringUtils.isNotBlank(qmBillConfig.getShopNo())) {
            req.setShopNo(qmBillConfig.getShopNo());
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        req.setStartTime(qmBillConfig.getStartTime().format(dateTimeFormatter));
        req.setEndTime(qmBillConfig.getEndTime().format(dateTimeFormatter));
        req.setPageNo(String.valueOf(qmBillConfig.getPageNo()));
        req.setPageSize(String.valueOf(qmBillConfig.getPageSize()));
        WdtReturnCollectQueryResponse response = client.execute(req);
        if ("".equals(response.getErrorCode())){
            JsonNode body = objectMapper.readTree(response.getBody());
            JsonNode res = body.get("response");
            if (res != null && "".equals(res.get("message").asText())){
                JsonNode orderList = res.get("order_list");
                for (int i = 0; i < orderList.size(); i++) {
                    JsonNode node = orderList.get(i);
                    String code = node.get("main_order_no").asText();
                    String receiptDate = node.get("finish_time").asText();
                    String invoiceCode = node.get("sales_system").asText();
                    String customerCode = node.get("shop_no").asText();
                    String costCenterCode = node.get("website").asText();
                    String totalAmount = node.get("total_amount").asText();
                    JsonNode detailsList = node.get("details_list");

                    OmsSalereturnbill omsSalereturnbill = new OmsSalereturnbill();
                    //售后订单号
                    omsSalereturnbill.setCode(code);
                    //来源系统
                    omsSalereturnbill.setSrcsys("wdt");
                    //查询系统中是否存在重复数据
                    List<OmsSalereturnbill> omsSalereturnbills = salereturnbillService.selectOmsSalereturnbillList(omsSalereturnbill);
                    if (StringUtils.isNotEmpty(omsSalereturnbills)){
                        throw new RuntimeException("系统中存在重复的销售退货单：" + code);
                    }
                    //事务类型编码
                    omsSalereturnbill.setTransactiontype("011");
                    //下单日期
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date parse = dateFormat.parse(receiptDate);
                    omsSalereturnbill.setTradecreatedat(parse);
                    //实际入库日期
                    omsSalereturnbill.setCloseat(parse);
                    //还原客户
                    BdCustomer bdCustomer = new BdCustomer();
                    bdCustomer.setCustomernumber(customerCode);
                    List<BdCustomer> bdCustomers = customerService.selectBdCustomerList(bdCustomer);
                    if (StringUtils.isEmpty(bdCustomers)){
                        errorMessage.append("[没有找到客户编码为："+ customerCode + "的客户]");
                        throw new RuntimeException(errorMessage.toString());
                    }
                    bdCustomer = bdCustomers.get(0);

                    //还原店铺
                    BdShop bdShop = new BdShop();
                    bdShop.setShopnumber(customerCode);
                    bdShop.setInvoicecode(invoiceCode);
                    List<BdShop> bdShops = shopService.selectBdShopList(bdShop);
                    if (StringUtils.isEmpty(bdShops)){
                        errorMessage.append("[根据店铺编码："+ customerCode +"和销售组织编码："+ invoiceCode +"没有找到店铺数据]");
                        throw new RuntimeException(errorMessage.toString());
                    }
                    bdShop = bdShops.get(0);
                    //售后成本中心编码
                    String costcenternumber = bdCustomer.getCostcenternumber();
                    String costcentername = bdCustomer.getCostcentername();
                    //将成本中心编码的获取来源改为直接从接口上获取
                    omsSalereturnbill.setSalescostcentercode(costCenterCode);
//                    omsSalereturnbill.setSalescostcentername(costcentername);
                    //售后单位编码
                    omsSalereturnbill.setCustomercode(customerCode);
                    //售后单位名称
                    omsSalereturnbill.setCustomername(bdCustomer.getCustomername());
                    //退出仓库
                    omsSalereturnbill.setExitwarehousecode(bdShop.getReturnwhcode());
                    omsSalereturnbill.setExitwarehousename(bdShop.getReturnwhname());
                    OmsOrgunit omsOrgunit = new OmsOrgunit();
                    omsOrgunit.setOrgnumber(invoiceCode);
                    List<OmsOrgunit> omsOrgunits = orgunitService.selectOmsOrgunitList(omsOrgunit);
                    if (StringUtils.isEmpty(omsOrgunits)){
                        errorMessage.append("没有找到组织：" + invoiceCode);
                        throw new RuntimeException(errorMessage.toString());
                    }
                    omsOrgunit = omsOrgunits.get(0);
                    //开票组织
                    omsSalereturnbill.setInvoicecode(invoiceCode);
                    omsSalereturnbill.setInvoicename(omsOrgunit.getOrgname());
                    //币别
                    omsSalereturnbill.setCurrency("CNY");
                    //汇率
                    omsSalereturnbill.setExchangerate(new BigDecimal(1));
                    //创建时间
                    omsSalereturnbill.setCreatetime(new Date());
                    //是否生成下游单据
                    omsSalereturnbill.setIscreatebill(0L);
                    //是否生成外部销售单
                    omsSalereturnbill.setIscreateoutbill(0L);

                    ArrayList<OmsSalereturnbillentry> omsSalereturnbillentries = new ArrayList<>();

                    for (int j = 0; j < detailsList.size(); j++) {
                        JsonNode billDetail = detailsList.get(j);
                        String refOrderCode = billDetail.get("collect_no").asText();
                        String isGift = billDetail.get("gift_type").asText();
                        String qty = billDetail.get("goods_count").asText();
                        String skuCode = billDetail.get("goods_no").asText();
                        String amount = billDetail.get("refund_amount").asText();
                        String price = billDetail.get("refund_price").asText();
                        String specNo = billDetail.get("spec_no").asText();
                        String tax = billDetail.get("tax").asText();
                        String taxRate = billDetail.get("tax_rate").asText();

                        //根据物料编码还原对象
                        BdMaterial bdMaterial = new BdMaterial();
                        bdMaterial.setMaterialnumber(skuCode);
                        List<BdMaterial> bdMaterials = materialService.selectBdMaterialList(bdMaterial);
                        if (StringUtils.isEmpty(bdMaterials)){
                            errorMessage.append("[没有找到物料：" + skuCode +"]");
                            throw new RuntimeException(errorMessage.toString());
                        }
                        bdMaterial = bdMaterials.get(0);

                        if ("0170010002".equals(skuCode)){
                            skuCode = "99.90.301";
                        }
                        OmsSalereturnbillentry omsSalereturnbillentry = new OmsSalereturnbillentry();
                        //商品编号
                        omsSalereturnbillentry.setSkucode(skuCode);
                        //商品名称
                        omsSalereturnbillentry.setSkuname(bdMaterial.getMaterialname());
                        //售后数量
                        omsSalereturnbillentry.setQty(new BigDecimal(qty));
                        //计量单位
                        String baseunitnumber = bdMaterial.getBaseunitnumber();
                        omsSalereturnbillentry.setUnit(baseunitnumber);
                        omsSalereturnbillentry.setBaseunit(baseunitnumber);
                        //基本售后数量
                        omsSalereturnbillentry.setBaseqty(new BigDecimal(qty));
                        //品控承担数量
                        omsSalereturnbillentry.setQualityundertakeqty(BigDecimal.ZERO);
                        //品控拒绝处理数量
                        omsSalereturnbillentry.setQualityrefuseqty(BigDecimal.ZERO);
                        //仓库承担待收数量
                        omsSalereturnbillentry.setWarehouseundertakeqty(new BigDecimal(qty));
                        //仓库拒绝处理数量
                        omsSalereturnbillentry.setWarehouserefuseqty(BigDecimal.ZERO);
                        //仓库承担无实物数量
                        omsSalereturnbillentry.setWarehousenoneqty(BigDecimal.ZERO);
                        //退入仓库数据
                        String returnwhcode = bdShop.getReturnwhcode();
                        String returnwhname = bdShop.getReturnwhname();
                        omsSalereturnbillentry.setReturnwarehousecode(returnwhcode);
                        omsSalereturnbillentry.setReturnwarehousename(returnwhname);
                        //售后日期
                        omsSalereturnbillentry.setRefundcreatedat(new SimpleDateFormat("yyyy-MM-dd").parse(receiptDate));
                        //获取税率
                        BigDecimal taxrate = bdMaterial.getTaxrate();
                        //格式化税率，用于后续计算
                        BigDecimal tempTaxrate = OmsTaskUtil.formatTaxRate(taxrate);
                        //不含税单价
                        BigDecimal noTaxPrice = new BigDecimal(price).divide(new BigDecimal(1).add(tempTaxrate), 6, BigDecimal.ROUND_HALF_UP);
                        omsSalereturnbillentry.setNotaxprice(noTaxPrice);
                        //不含税总金额
                        omsSalereturnbillentry.setNotaxamount(noTaxPrice.multiply(new BigDecimal(qty)));
                        //含税单价
                        omsSalereturnbillentry.setTaxprice(new BigDecimal(price));
                        //含税总金额
                        omsSalereturnbillentry.setTaxamount(new BigDecimal(amount));
                        //税额
                        omsSalereturnbillentry.setTaxrate(taxrate);
                        //税额
                        omsSalereturnbillentry.setTax(omsSalereturnbillentry.getTaxamount().subtract(omsSalereturnbillentry.getNotaxamount()));
                        //是否赠品
                        omsSalereturnbillentry.setIsgift(Long.valueOf(isGift));
                        //collect_no放到备注字段上
                        omsSalereturnbillentry.setRemark(refOrderCode);
                        omsSalereturnbillentries.add(omsSalereturnbillentry);
                    }
                    omsSalereturnbill.setOmsSalereturnbillentryList(omsSalereturnbillentries);
                    salereturnbillService.insertOmsSalereturnbill(omsSalereturnbill);
                }
            }else {
                throw new RuntimeException(String.valueOf(res.get("message")));
            }
        }else {
            throw new RuntimeException(response.getMessage());
        }
    }
}
